package xyz.kail.demo.async.jdk5;

import java.util.concurrent.*;
import java.util.function.Consumer;

public class FutureMain {

    /**
     * 异步提交-阻塞获取
     */
    private static void blockFuture() throws ExecutionException, InterruptedException {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        try {
            // 异步提交
            Future<String> future = executorService.submit(new Jdk7Future(5));
            System.out.println(future.isCancelled());
            System.out.println(future.isDone());
            // 阻塞获取结果
            System.out.println("阻塞获取结果" + future.get());
        } finally {
            executorService.shutdown();
        }
    }

    private static void spinFuture() {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        try {
            // 异步提交
            Future<String> future = executorService.submit(new Jdk7Future(5));
            for (; !future.isCancelled() && !future.isDone(); TimeUnit.MILLISECONDS.sleep(500)) {
                System.out.println("自旋" + future.isCancelled() + "-" + future.isDone());
            }
            // 阻塞获取结果
            System.out.println("阻塞获取结果" + future.get());
        } catch (ExecutionException | InterruptedException e) {
            e.printStackTrace();
        } finally {
            executorService.shutdown();
        }
    }


    /**
     * 注入回调
     */
    private static void asyncFuture(Consumer<String> callback) {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        ExecutorService callbackExecutor = Executors.newSingleThreadExecutor();
        try {
            // 异步提交
            Future<String> future = executorService.submit(new Jdk7Future(5));

            callbackExecutor.submit(() -> {
                try {
                    callback.accept(future.get());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        } finally {
            executorService.shutdown();
            callbackExecutor.shutdown();
        }
    }

    public static void main(String[] args) throws Exception {
        // spinFuture();

//        asyncFuture(s -> System.out.println("执行完了，结果" + s));
//        System.out.println("main end");


    }

    private static final class Jdk7Future implements Callable<String> {

        private long sleep;

        public Jdk7Future(long sleep) {
            this.sleep = sleep;
        }

        @Override
        public String call() throws Exception {
            TimeUnit.SECONDS.sleep(sleep);
            return String.valueOf(System.currentTimeMillis());
        }
    }

}

/*
 * 问题
 * - futurn.get 方法 是如何阻塞的？？
 * - 有没有更好的方式
 */
